package service_manager

import (
	"fmt"
	"google.golang.org/grpc"
)

const (
	DEVICE_TV    = "tv"
	DEVICE_PHONE = "phone"
	SERVICE_PORT = 8000
)

var (
	DEVICE_NAME = "pixel4"
	DEVICE_TYPE = "mobile"
	DEVICE_TAG  = "1234"
)

const (
	STATUS_UNVERIFY = 1
	STATUS_VERIFIED = 2
)

type DeviceInfo struct {
	Name      string
	DType     string
	Tag       string // 设备序列号，用来区分不同设备
	VerifyMsg string
	Status    int32
	DevAddr   string // 当前设备DMS监听地址
}

type AsyncLog chan string

func InitDevice(dv string) {
	if dv == DEVICE_TV {
		DEVICE_TYPE = DEVICE_TV
		DEVICE_TAG = "1234"
	} else if dv == DEVICE_PHONE {
		DEVICE_TYPE = DEVICE_PHONE
		DEVICE_TAG = "5678"
	}
	DEVICE_NAME = "pixel4@" + DEVICE_TYPE
}

// 通过认证的设备
type DeviceManager struct {
	DeviceMap map[string]*DeviceInfo // sessionKey -> Device
	CurDv     DeviceInfo
	logQueue  AsyncLog
}

func NewDeviceManager(logger AsyncLog) *DeviceManager {
	return &DeviceManager{
		DeviceMap: make(map[string]*DeviceInfo),
		logQueue:  logger,
	}
}

type ServiceManager struct {
	DM       *DeviceManager
	CPM      *CapabilityManager
	DMServer *grpc.Server
	LogQueue AsyncLog
}

func InitDMService(ip string, ty string) *ServiceManager {
	dms := &ServiceManager{}
	dms.LogQueue = make(chan string, 10)
	InitDevice(ty)
	DM := NewDeviceManager(dms.LogQueue)
	dms.DM = DM
	DM.CurDv = DeviceInfo{
		Name:  DEVICE_NAME,
		DType: DEVICE_TYPE,
		Tag:   DEVICE_TAG + "-" + DEVICE_NAME,
	}
	DM.CurDv.DevAddr = fmt.Sprintf("%s:%d", ip, SERVICE_PORT)
	return dms
}

func (smc *ServiceManager) StartRPCServer() {
	smc.DMServer = newServerRPC(smc.DM.CurDv.DevAddr, smc.DM)
}

// todo
func (smc *ServiceManager) DiscoverDevices() {
}

func (smc *ServiceManager) Stop() {
	if smc.DMServer != nil {
		smc.DMServer.Stop()
	}
}

func (dms *DeviceManager) InitDeviceVerification(remoteDevTag string) {
	verifyCode := "12345"
	dms.logQueue <- fmt.Sprintf("Device Verify Code : %s", verifyCode)
	dev := &DeviceInfo{Status: STATUS_UNVERIFY, VerifyMsg: verifyCode}
	dms.DeviceMap[remoteDevTag] = dev
}

func (dms *DeviceManager) RegisterDevices(name, dt, tag string, msg string) bool {
	if dev, ok := dms.DeviceMap[tag]; ok {
		if dev.VerifyMsg == msg {
			dev.Name = name
			dev.Tag = tag
			dev.DType = dt
			dms.logQueue <- fmt.Sprintf("Success to Register Dev: %s", dev.Tag)
			return true
		}
		dms.logQueue <- fmt.Sprintf("Verify Code is Incorrect: %s", msg)
	}
	dms.logQueue <- fmt.Sprintf("Devices Does not Exist: %s", tag)
	return false
}

//func (d *DeviceManager)

//func (d *DeviceManager)

type Capability string

type CapabilityPolicy struct {
	GrantedCaps []Capability
	Token       string
}

type AppCapability struct {
	device  *DeviceInfo
	caps    map[Capability]bool
	granted *CapabilityPolicy
}

type CapabilityManager struct {
	appMap map[string]AppCapability
}
